/*!
** @mainpage
** This is the documentation for the Firefox add-on Keep My Bookmarks !
** You will be able to see prototypes of each function, and  how they are
** interacting which each others.<br />
** Website : http://adrien.frenchcomp.net
*/

/*!
** @file keepmybookmarks.js
** @brief main file
** @author Adrien MOGENET
*/


////////////////////////////////////////////////////////////////////////////////
//
// CONSTANTS
//
////////////////////////////////////////////////////////////////////////////////


/*!
** @def DEBUG	: state of the debug mode
** @todo set @c DEBUG to false before packaging !
*/
const DEBUG			= false;
const VERSION			= 0.1;
const APP_URI			= "chrome://keepmybookmarks";
const MODE_NETWORK		= 0;
const MODE_LOCAL		= 1;


////////////////////////////////////////////////////////////////////////////////
//
// GLOBAL OBJECTS
//
////////////////////////////////////////////////////////////////////////////////


const nsIFilePicker		= Components.interfaces.nsIFilePicker;
var historyService		= Components.classes["@mozilla.org/browser/nav-history-service;1"]
				.getService (Components.interfaces.nsINavHistoryService);
var bookmarksService		= Components.classes["@mozilla.org/browser/nav-bookmarks-service;1"]
				.getService (Components.interfaces.nsINavBookmarksService);

/*!
** @var root : long long
** @brief (id of the root folder for bookmarks)
** @todo User will be able to select the root directory
*/
var root			= bookmarksService.bookmarksMenuFolder;

/*!
** @var listOfBookmarks : string.
** @brief Store the complete list of bookmarks
*/
var listOfBookmarks		= "";


////////////////////////////////////////////////////////////////////////////////
//
// FEATURES FUNCTIONS
// ------------------
// Implementation of the different features
//
////////////////////////////////////////////////////////////////////////////////


/*!
** @brief upload the bookmarks on the server.
** The file is uploaded with the favorite method of the user (FTP, HTTP...)
** @see var @c uploader, in uploader.js
** @todo think about the port option.
** @bug no error when invalid password
** @author Adrien MOGENET
*/

function upload_bookmarks ()
{
    var success;
    var scheme	 = prefSchemeGet ();
    var user	 = prefUserGet ();
    var password = prefPasswordGet (user);
    var host	 = prefHostGet ();
    var path	 = prefPathGet ();
    var port	 = 21;
    var content	 = getBookmarks ();

    success = uploader.upload (scheme, user, password, host, path, port, content);
}

/*!
** @brief create file with bookmarks on hdd
** @author Adrien MOGENET
** @return bool : success or not
** @todo Handle errors (directory doesn't exist...)
*/

function copy_bookmarks ()
{
    var filedir	 = prefLocalPathGet ();
    var filename = "bookmarks.html";
    var foStream = Components.classes["@mozilla.org/network/file-output-stream;1"]
                 .createInstance(Components.interfaces.nsIFileOutputStream);
    var file	 = Components.classes["@mozilla.org/file/local;1"]
		 .createInstance(Components.interfaces.nsILocalFile);
    var data	 = getBookmarks ();

    if (DEBUG)
	alert ('Copy bookmarks on HDD : ' + filename);

    file.initWithPath (filedir + '/' + filename);
    foStream.init(file, 0x02 | 0x08 | 0x20, 0666, 0);
    foStream.write (data, data.length);
    foStream.close ();
}

/*!
** @brief Recursive function. Complete the list of bookmarks.
** Fill the @c listOfBookmarks global variable.
** @todo Get the favicon.
** @author Adrien MOGENET
*/
function exploreBookmarksFolder (id)
{
    var options			= historyService.getNewQueryOptions ();
    var query			= historyService.getNewQuery ();
    var folder			= id;

    // fixme : there is a bug with the current version of Firefox (3 beta 3)
    // uncomment this line at the end
    //options.setGroupingMode (options.GROUP_BY_FOLDER);
    query.setFolders ([folder], 1);

    var result		= historyService.executeQuery (query, options);
    var rootNode	= result.root;

    rootNode.containerOpen = true;

    for (var i = 0; i < rootNode.childCount; i ++)
    {
	var node = rootNode.getChild(i);

	if (node.type == node.RESULT_TYPE_FOLDER)
	{
	    listOfBookmarks += '<dt><h3> ' + node.title + '</h3><dl><p>';
	    exploreBookmarksFolder(node.itemId);
	    listOfBookmarks += '</p></dl>';
	}
	else
	{
	    listOfBookmarks += '<dt><a href="'+ node.uri +'">' + node.title + '</a>';
	    listOfBookmarks += '<dd>';
	}
    }
    rootNode.containerOpen = false;
}

/*!
** @brief Generates the list of bookmarks
** @return string : bookmaks
** @author Adrien MOGENET
*/
function getBookmarks ()
{
    var bookmarks = "";
    listOfBookmarks += '<html><head><link rel="stylesheet" type="text/css" href="bookstyle.css"/><meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"><title>Bookmarks</title></head><body><h1>Bookmarks Menu</h1><dl><p>';
    exploreBookmarksFolder (root);
    listOfBookmarks += '</p></dl></body></html>';
    bookmarks = listOfBookmarks;
    listOfBookmarks = "";
    return bookmarks;
}

/*!
** @brief Main function. Performs all the actions
** Export the bookmarks on a server, export on a specified location.
** @author Adrien MOGENET
*/
function keepmybookmarks ()
{
    if (prefNetworkModeGet ())
	upload_bookmarks ();

    if (prefLocalModeGet ())
	copy_bookmarks ();
}

/*!
** @brief Show a folder picker.
** @return string : path of selected folder
** @author Adrien MOGENET
*/
function selectFolder ()
{
    var picker	= Components.classes["@mozilla.org/filepicker;1"]
		.createInstance(nsIFilePicker);
    var path	= "";

    picker.init (window, "Chose a folder", nsIFilePicker.modeGetFolder);
    picker.appendFilters (nsIFilePicker.filterAll | nsIFilePicker.filterText);

    var rv	= picker.show();

    if (rv == nsIFilePicker.returnOK || rv == nsIFilePicker.returnReplace)
	path = picker.file.path;
    return path;
}


////////////////////////////////////////////////////////////////////////////////
//
// EVENT FUNCTIONS
// ---------------
// Following functions are called according to specific events
// ie: app loaded, button pressed...
//
////////////////////////////////////////////////////////////////////////////////

/*!
** @brief When @c choseFolder button is pressed
** @author Adrien MOGENET
*/
function onChoseFolder ()
{
    var path	= selectFolder ();
    document.getElementById ('localpath').value = path;
}

/*!
** @brief When @c OK button of the app is pressed.
** We save all the preferences of the user.
** @see preferences.js, function @c savePreferences()
** @author Adrien MOGENET
*/
function appValidate ()
{
    savePreferences ();
}

/*!
** @brief When 'Cancel' button of the app is pressed
** @author Adrien MOGENET
*/
function appCancel ()
{
    return ;
}

/*!
** @brief When 'Apply' button of the app is pressed.
** Here, XUL application doesn't exit but we save Preferences.
** @see preferences.js, function @c savePreferences()
** @author Adrien MOGENET
*/
function appApply ()
{
    savePreferences ();
}

/*!
** @brief When the app is loaded.
** The different fields are initialized with stored values.
** @see preferences.js, with function @c retrievePreferences()
** @author Adrien MOGENET
*/
function appLoad ()
{
    retrievePreferences ();
}

/*!
** @brief When the browser is closed.
** The bookmarks are uploaded if the option 'auto-upload' is enabled.
** @see function @c keepmybookmarks()
** @author Adrien MOGENET
*/
function browserClosed ()
{
    if (prefAutoUploadGet ())
	keepmybookmarks ()
}

/*
** When Firefox is unloaded, we launch the main function of this
** extension
*/

window.addEventListener("unload", browserClosed, false);


////////////////////////////////////////////////////////////////////////////////
//
// DEBUG FUNCTIONS
// ---------------
// funcion directly called during development, but only during the
// development
//
////////////////////////////////////////////////////////////////////////////////


function openMainWindow ()
{
    window.open("chrome://keepmybookmarks/content/keepmybookmarks.xul", "bmarks", "chrome,width=430,height=520");
}

